package cn.edu.ncut.cs.springboot.petmanagementsystem.controller;

import cn.edu.ncut.cs.springboot.petmanagementsystem.Util.JwtUtil;
import cn.edu.ncut.cs.springboot.petmanagementsystem.common.Result;
import cn.edu.ncut.cs.springboot.petmanagementsystem.dto.LoginRequest;
import cn.edu.ncut.cs.springboot.petmanagementsystem.dto.LoginResponse;
import cn.edu.ncut.cs.springboot.petmanagementsystem.dto.RegisterRequest;
import cn.edu.ncut.cs.springboot.petmanagementsystem.pojo.User;
import cn.edu.ncut.cs.springboot.petmanagementsystem.service.UserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/auth")
@Tag(name = "认证与权限模块", description = "用户登录、注册、token刷新等认证相关接口")
public class AuthController {

    @Autowired
    private UserService userService;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Operation(summary = "用户登录", description = "用户登录接口，登录成功后返回JWT Token")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "登录成功",
                    content = @Content(schema = @Schema(implementation = LoginResponse.class))),
            @ApiResponse(responseCode = "400", description = "用户名或密码错误")
    })
    @PostMapping("/login")
    public Result<?> login(@Valid @RequestBody LoginRequest request) {
        try {
            User user = userService.login(request.getUsername(), request.getPassword());
            if (user == null) {
                return Result.error("用户名或密码错误");
            }

            // 检查用户状态
            if (user.getStatus() == 0) {
                return Result.error("账号已被禁用");
            }

            // 生成Token
            Map<String, Object> claims = new HashMap<>();
            String role = user.getUserType() == 2 ? "ROLE_ADMIN" : "ROLE_USER";
            claims.put("role", role);
            claims.put("userId", user.getId());

            String token = JwtUtil.generateToken(user.getUsername(), claims);

            // 构建登录响应
            LoginResponse loginResponse = LoginResponse.builder()
                    .token(token)
                    .username(user.getUsername())
                    .role(role)
                    .userType(user.getUserType())
                    .userId(user.getId())
                    .realName(user.getRealName())
                    .email(user.getEmail())
                    .phone(user.getPhone())
                    .build();

            return Result.success("登录成功", loginResponse);
        } catch (Exception e) {
            log.error("登录失败", e);
            return Result.error("登录失败: " + e.getMessage());
        }
    }

    @Operation(summary = "用户注册", description = "新用户注册接口，注册成功后需要登录获取Token")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "注册成功"),
            @ApiResponse(responseCode = "400", description = "注册失败，用户名已存在或参数验证失败")
    })
    @PostMapping("/register")
    public Result<?> register(@Valid @RequestBody RegisterRequest request) {
        try {
            // 验证两次密码是否一致
            if (!request.getPassword().equals(request.getConfirmPassword())) {
                return Result.error("两次密码输入不一致");
            }

            // 检查用户名是否已存在
            User existUser = userService.getUserByUsername(request.getUsername());
            if (existUser != null) {
                return Result.error("用户名已存在");
            }

            // 构建用户对象
            User user = new User();
            user.setUsername(request.getUsername());
            user.setPassword(passwordEncoder.encode(request.getPassword())); // 加密密码
            user.setEmail(request.getEmail());
            user.setPhone(request.getPhone());
            user.setRealName(request.getRealName());
            user.setUserType(1); // 默认为普通用户
            user.setStatus(1); // 默认状态为正常

            // 保存用户
            boolean success = userService.register(user);
            if (success) {
                Map<String, Object> result = new HashMap<>();
                result.put("username", user.getUsername());
                result.put("message", "注册成功，请登录");
                return Result.success("注册成功", result);
            } else {
                return Result.error("注册失败，请稍后重试");
            }
        } catch (Exception e) {
            log.error("注册失败", e);
            return Result.error("注册失败: " + e.getMessage());
        }
    }

    @Operation(summary = "用户退出登录", description = "用户退出登录接口（JWT无状态，客户端删除token即可）")
    @PostMapping("/logout")
    public Result<?> logout() {
        // JWT是无状态的，客户端删除token即可
        return Result.success("退出成功");
    }

    @Operation(summary = "刷新Token", description = "刷新JWT Token，延长登录有效期")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "刷新成功"),
            @ApiResponse(responseCode = "400", description = "Token无效")
    })
    @GetMapping("/refresh")
    public Result<?> refreshToken(@RequestHeader("Authorization") String authHeader) {
        try {
            if (authHeader == null || !authHeader.startsWith("Bearer ")) {
                return Result.error("Token无效");
            }

            String token = authHeader.substring(7);
            String username = JwtUtil.getUsername(token);
            
            if (username == null) {
                return Result.error("Token无效");
            }

            User user = userService.getUserByUsername(username);
            if (user == null) {
                return Result.error("用户不存在");
            }

            // 生成新Token
            Map<String, Object> claims = new HashMap<>();
            String role = user.getUserType() == 2 ? "ROLE_ADMIN" : "ROLE_USER";
            claims.put("role", role);
            claims.put("userId", user.getId());

            String newToken = JwtUtil.generateToken(user.getUsername(), claims);

            Map<String, Object> result = new HashMap<>();
            result.put("token", newToken);
            return Result.success("刷新成功", result);
        } catch (Exception e) {
            log.error("刷新Token失败", e);
            return Result.error("刷新失败");
        }
    }

    @Operation(summary = "获取当前用户权限", description = "获取当前登录用户的角色和权限信息")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "获取成功"),
            @ApiResponse(responseCode = "400", description = "用户不存在")
    })
    @GetMapping("/permissions")
    public Result<?> getPermissions() {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            String username = authentication.getName();
            User user = userService.getUserByUsername(username);

            if (user == null) {
                return Result.error("用户不存在");
            }

            Map<String, Object> permissions = new HashMap<>();
            String role = user.getUserType() == 2 ? "ROLE_ADMIN" : "ROLE_USER";
            permissions.put("role", role);
            permissions.put("userType", user.getUserType());
            permissions.put("permissions", user.getUserType() == 2 ? 
                new String[]{"user:read", "user:write", "admin:all"} : 
                new String[]{"user:read", "user:write"});

            return Result.success(permissions);
        } catch (Exception e) {
            log.error("获取权限信息失败", e);
            return Result.error("获取权限信息失败");
        }
    }

}
